#include<stdio.h>
#include<malloc.h>
#include<string.h>
typedef enum
{
	INT,
	FLOAT,
	STRING
}DataType;

typedef struct Node{
	void* val;
	DataType type;
	struct Node* pre;
	struct Node* next;
}node;

typedef struct double_list{
	node* head;
	node* tail;
	int len;
}double_list;

double_list* init()
{	double_list* rt=(double_list*)malloc(sizeof(double_list));
	rt->head=(node*)malloc(sizeof(node));
	rt->tail=rt->head;
	return rt;
}

void push(double_list* dl,void* val,DataType type)
{
	node* newnode=(node*)malloc(sizeof(node));
	newnode->val=(void*)malloc(sizeof(void*));
	memcpy(newnode->val,val,sizeof(val));
	newnode->type=type;
	(dl)->tail->next=newnode;
	newnode->pre=(dl)->tail;
	(dl)->tail=newnode;
	(dl)->tail->next=NULL;
	(dl)->len+=1;
}

node* get_index_node(double_list* dl,int index)
{
	node* rb=(node*)malloc(sizeof(node));
	if(index>dl->len)
	{
		printf("%s\n","ERROR:index is longer than listlen!");
		return NULL;
	}
	int listlen=dl->len;
	int len2=listlen-index;
	if(index>len2)
	{
		rb=dl->tail;
		while(len2)
		rb=rb->pre;
	}
	else
	{	rb=dl->head->next;
		while(index--)
		rb=rb->next;
	}
	return rb;
}

void delete(double_list* dl,int index)
{
	 if(index>dl->len)
	 {
		printf("%s\n","ERROR:index longer than listlen");
		return;
	 } 
	 node* tar=get_index_node(dl,index);

	

	 if(tar==dl->head->next)
	 {
		 dl->head->next=tar->next;
		 tar->pre=dl->head;
	 }
	 else if(tar==dl->tail)
		 tar->pre->next=NULL;
	 else
	 {
	tar->pre->next=tar->next;
	tar->next->pre=tar->pre;
	 }
	free(tar->val);
	free(tar);
	dl->len-=1;
}

void change(double_list* dl,int index,void* val,DataType type)
{
	node* tar=get_index_node(dl,index);
 
	tar->val=val;
	tar->type=type;
}

void show(double_list* dl)
{
	node* tmp=dl->head->next;
	while(tmp)
	{
		if(tmp->type==INT)
			printf("%d\t",*(int*)tmp->val);
		else if(tmp->type==FLOAT)
			printf("%f\t",*(float*)tmp->val);
		else
			printf("%s\t",(char*)tmp->val);
		tmp=tmp->next;
	}

}

void freelist(double_list** dl)
{
	node* tmp;
	while(tmp)
	{
		tmp=(*dl)->head->next;
		free((*dl)->head->val);
		free((*dl)->head);
		(*dl)->head=tmp;
	}
	*dl=NULL;

}

